﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using RealEstateBrowser.Helpers;
using System.IO;
using Microsoft.Win32;
using RealEstateBrowser.Commands;

namespace RealEstateBrowser.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<OfferViewModel> offers;
        private ObservableCollection<TownViewModel> towns;
        private ObservableCollection<DistrictViewModel> districts;
        private TownViewModel currentTown;
        private DistrictViewModel currentDistrict;
        private OfferViewModel currentOffer;
        private ObservableCollection<OfferTypeViewModel> offerTypes;
        private ObservableCollection<EstateTypeViewModel> estateTypes;
        private ObservableCollection<ExtraViewModel> extras;
        private AdvancedSearchViewModel advancedSearchProperties;
        private FilterCommand filterCommand;

        public MainViewModel()
        {
            towns = new ObservableCollection<TownViewModel>(Skochubra.GetAllTowns());
            currentTown = towns.FirstOrDefault();
            districts = currentTown.Districts;
            currentDistrict = districts.FirstOrDefault();
            UpdateOffers();
            currentOffer = Offers.FirstOrDefault();
            advancedSearchProperties = new AdvancedSearchViewModel();
            filterCommand = new Commands.FilterCommand(this);

            OfferTypes = new ObservableCollection<OfferTypeViewModel>(Skochubra.GetOfferTypes());
            Extras = new ObservableCollection<ExtraViewModel>(Skochubra.GetExtras());
            EstateTypes = new ObservableCollection<EstateTypeViewModel>(Skochubra.GetEstateTypes());
        }
  
        public FilterCommand FilterCommand
        {
            get
            {
                return filterCommand;
            }
            set
            {
                filterCommand = value;
            }
        }

        public AdvancedSearchViewModel AdvancedSearchProperties
        {
            get
            {
                return advancedSearchProperties;
            }
            set
            {
                advancedSearchProperties = value;
            }
        }

        public ObservableCollection<OfferTypeViewModel> OfferTypes
        {
            get
            {
                return offerTypes;
            }
            set
            {
                if (offerTypes != value)
                {
                    offerTypes = value;
                    OnPropertyChanged("OfferTypes");
                }
            }
        }

        public ObservableCollection<EstateTypeViewModel> EstateTypes
        {
            get
            {
                return estateTypes;
            }
            set
            {
                if (estateTypes != value)
                {
                    estateTypes = value;
                    OnPropertyChanged("EstateTypes");
                }
            }
        }

        public ObservableCollection<ExtraViewModel> Extras
        {
            get
            {
                return extras;
            }
            set
            {
                if (extras != value)
                {
                    extras = value;
                    OnPropertyChanged("Extras");
                }
            }
        }

        public OfferViewModel CurrentOffer
        {
            get
            {
                return currentOffer;
            }
            set
            {
                if (this.currentOffer != value)
                {
                    currentOffer = value;
                    OnPropertyChanged("CurrentOffer");
                }
            }
        }

        private void UpdateOffers()
        {
            Offers = new ObservableCollection<OfferViewModel>(Skochubra.GetOffers(currentTown.TownName, CurrentDistrict.DistrictName));
        }

        public ObservableCollection<OfferViewModel> Offers
        {
            get
            {
                return offers;
            }
            set
            {
                if (this.offers != value)
                {
                    offers = value;
                    OnPropertyChanged("Offers");
                }
            }
        }

        public ObservableCollection<TownViewModel> Towns
        {
            get
            {
                return towns;
            }
            set
            {
                if (this.towns != value)
                {
                    towns = value;
                    OnPropertyChanged("Towns");
                }
            }
        }

        public ObservableCollection<DistrictViewModel> Districts
        {
            get
            {
                return districts;
            }
            set
            {
                if (this.districts != value)
                {
                    districts = value;
                    OnPropertyChanged("Districts");
                }
            }
        }

        public TownViewModel CurrentTown
        {
            get
            {
                return currentTown;
            }
            set
            {
                if (this.currentTown != value)
                {
                    currentTown = value;
                    Districts = currentTown.Districts;
                    OnPropertyChanged("CurrentTown");
                }
            }
        }

        public DistrictViewModel CurrentDistrict
        {
            get
            {
                return currentDistrict;
            }
            set
            {
                if (this.currentDistrict != value)
                {
                    currentDistrict = value;
                    UpdateOffers();
                    OnPropertyChanged("CurrentDistrict");
                }
            }
        }

        internal void FilterOffers()
        {
            Offers = new ObservableCollection<OfferViewModel>(Skochubra.GetAllOffers());

            if (AdvancedSearchProperties.Id != null)
            {
                Offers = new ObservableCollection<OfferViewModel>(
                    Offers
                          .Where(o => o.Offer.OfferID == int.Parse(AdvancedSearchProperties.Id))
                          .ToList());
            }

            if (AdvancedSearchProperties.Active != null)
            {
                Offers = new ObservableCollection<OfferViewModel>(
                    Offers.Where(o => o.Offer.Active == AdvancedSearchProperties.Active));
            }

            if (AdvancedSearchProperties.OfferType != null)
            {
                Offers = new ObservableCollection<OfferViewModel>(Offers
                                                                        .Where(o => o.Offer.OfferType.OfferTypeID == AdvancedSearchProperties.OfferType.OfferType.OfferTypeID)
                                                                        .ToList());
            }

            if (AdvancedSearchProperties.EstateType != null)
            {
                Offers = new ObservableCollection<OfferViewModel>(Offers
                                                                        .Where(o => o.Offer.EstateType.EstateTypeID == AdvancedSearchProperties.EstateType.EstateType.EstateTypeID)
                                                                        .ToList());
            }

            if (AdvancedSearchProperties.Date != null)
            {
                Offers = new ObservableCollection<OfferViewModel>(
                    Offers.Where(o=>o.Offer.PublishDate.Date.Day == advancedSearchProperties.Date.Value.Day && 
                                    o.Offer.PublishDate.Date.Month == AdvancedSearchProperties.Date.Value.Month &&
                                    o.Offer.PublishDate.Date.Year == advancedSearchProperties.Date.Value.Year).ToList());
            }

            ObservableCollection<OfferViewModel> offers = new ObservableCollection<OfferViewModel>();

            foreach (OfferViewModel offer in Offers)
            {
                if (CheckExtras(offer))
                {
                    offers.Add(offer);
                }
            }

            Offers = offers;
        }
  
        private bool CheckExtras(OfferViewModel offer)
        {
            var extrasNames = (from e in offer.Offer.Extras
                              select e.ExtraName).ToList();

            foreach (ExtraViewModel extra in AdvancedSearchProperties.Extras)
            {
                if (extra.IsChecked && !extrasNames.Contains(extra.Extra.ExtraName))
                {
                    return false;
                }
            }

            return true;
        }
    }
}